package com.ikas.ai.handle;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.ikas.ai.utils.JsonUtil;
import org.apache.commons.lang3.StringUtils;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 返回给前台的json结果
 *
 * @author HXH
 */
public class JsonResult {

    public final static String TAG_CODE = "code";
    public final static String TAG_MSG = "msg";
    public final static String TAG_DATA = "data";
    public final static String TAG_URL = "url";
    public final static String TAG_REMARK = "remark";
    public static final String URL_LOGIN = "/login";
    private boolean formatDouble = false;
    /**
     * 结果类型
     */
    private JsonResultType type;
    private static String message = "";
    private static String remark = "";
    private final Map<String, Object> items = new LinkedHashMap<>();

    /**
     * 构造函数
     */
    public JsonResult() {
        this.type = JsonResultType.OK;
        this.items.put(TAG_CODE, this.getType().getValue());
        this.items.put(TAG_MSG, this.getMessage());
        this.items.put(TAG_REMARK, this.getRemark());
    }

    /**
     * 构造函数
     *
     * @param type 结果类型
     */
    public JsonResult(JsonResultType type) {
        this();
        this.setType(type);
    }

    public JsonResult(JsonResultType type, String message) {
        this(type);
        this.setMessage(message);
    }

    /**
     * 正常返回的无参静态方法
     */
    public static JsonResult ok() {
        return new JsonResult(JsonResultType.OK, "操作成功");
    }

    /**
     * 正常返回的有值静态方法
     */
    public static <T> JsonResult ok(T result) {
        JsonResult json = ok();
        json.add(result);
        return json;
    }

    /**
     * 无参异常返回
     *
     * @return
     */
    public static JsonResult error() {
        return error(JsonResultType.ERROR);
    }

    /**
     * 带参异常返回
     *
     * @param type
     * @return
     */
    public static JsonResult error(JsonResultType type) {
        return error(type, message);
    }

    /**
     * 异常返回错误信息
     *
     * @return
     */
    public static JsonResult error(String message) {
        return error(JsonResultType.ERROR, message);
    }

    /**
     * 带参异常返回
     *
     * @param type
     * @return
     */
    public static JsonResult error(JsonResultType type, String message) {
        return new JsonResult(type, message);
    }


    /**
     * 正常返回的无参静态方法
     */
    public static String success() {
        JsonResult json = ok();
        return json.toJSON();
    }

    /**
     * 正常返回的有值静态方法
     */
    public static <T> String success(T result) {
        JsonResult json = ok();
        json.add(result);
        return json.toJSON();
    }

    /**
     * 失败返回的无参静态方法
     */
    public static String fail() {
        JsonResult json = error();
        return json.toJSON();
    }

    /**
     * 失败返回的无参静态方法
     */
    public static String fail(String msg) {
        JsonResult json = error(msg);
        return json.toJSON();
    }

    /**
     * 增加传出的结果
     *
     * @param key
     * @param value
     * @return
     */
    public JsonResult add(String key, Object value) {
        if (this.items.containsKey(key)) {
            this.items.remove(key);
        }
        boolean bsuccess = false;
        if (value instanceof String) {
            String tmp = value.toString();
            if (JsonUtil.isJsonObject(tmp)) {
                JSONObject obj = JSON.parseObject(tmp, Feature.OrderedField);
                this.items.put(key, obj);
                bsuccess = true;
            } else if (JsonUtil.isJsonArray(tmp)) {
                JSONArray obj = JSON.parseArray(tmp);
                this.items.put(key, obj);
                bsuccess = true;
            }
        }
        if (!bsuccess) {
            this.items.put(key, value);
        }
        return this;
    }

    /**
     * 增加集合到集合中
     *
     * @param data
     * @param total
     * @return
     */
    public JsonResult add(List<?> data, int total) {
        this.add(TAG_DATA, data);
        this.add("iTotalRecords", total);
        this.add("iTotalDisplayRecords", total);
        return this;
    }

    /**
     * 增加单个数据对象到集合中
     *
     * @param data
     * @return
     */
    public JsonResult add(Object data) {
        this.add(TAG_DATA, data);
        return this;
    }

    /**
     * 移除传出的结果
     *
     * @param key
     * @return
     */
    public JsonResult remove(String key) {
        this.items.remove(key);
        return this;
    }

    /**
     * 输出JSON字符串
     *
     * @return
     */
    public String toJSON() {
        this.items.put(TAG_CODE, type.getValue());
        if (type == JsonResultType.SESSIONTIMEOUT) {
            this.items.put(TAG_URL, URL_LOGIN);
        }
        this.items.put(TAG_MSG, this.getMessage());
        if (StringUtils.isNotBlank(this.getRemark())) {
            this.items.put(TAG_REMARK, this.getRemark());
        }

        return JSON.toJSONString(items, formatDouble ? JsonSerialize.all() : JsonSerialize.instance(),
                SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullStringAsEmpty, SerializerFeature.WriteNullListAsEmpty, SerializerFeature.SortField, SerializerFeature.MapSortField);
    }

    public JsonResult formatDouble() {
        formatDouble = true;
        return this;
    }

    /**
     * 输出参数列表
     *
     * @return
     */
    public Map<String, Object> getResult() {
        this.items.put(TAG_CODE, this.getType().getValue());
        return items;
    }

    /**
     * 尝试获取data数据
     * <p>
     * 该方法不做任何数据类型校验，不对任何错误进行处理，调用前需自行确认值是否获取正确
     *
     * @return T
     * @author ly
     */
    @SuppressWarnings("unchecked")
    public <T> T tryGetData() {
        return (T) getResult().get(TAG_DATA);
    }

    /**
     * 获取data数据 - 无该类型时返回空
     *
     * @param tClass 泛型类
     * @return T 具体值
     * @author ly
     */
    @SuppressWarnings("unchecked")
    public <T> T getData(Class<T> tClass) {
        Object o = getResult().get(TAG_DATA);
        return tClass.isInstance(o) ? (T) o : null;
    }


    /**
     * 获得结果类型
     *
     * @return
     */
    public JsonResultType getType() {
        return type;
    }

    /**
     * 设置结果类型
     *
     * @param type
     * @return
     */
    public JsonResult setType(JsonResultType type) {
        this.type = type;
        this.setMessage(type.toString());
        return this;
    }

    /**
     * 返回消息
     *
     * @return
     */
    public String getMessage() {
        return message;
    }

    /**
     * 设置返回的消息
     *
     * @param message
     * @return
     */
    public JsonResult setMessage(String message) {
        JsonResult.message = message;
        return this;
    }

    /**
     * 获取备注信息
     *
     * @return
     */
    public String getRemark() {
        return remark;
    }

    /**
     * 设置返回备注信息
     *
     * @param remark
     * @return
     */
    public JsonResult setRemark(String remark) {
        JsonResult.remark = remark;
        return this;
    }
}
